1include <gridfinity-rebuilt-utility.scad>
2include <standard.scad>
3
4// ===== INFORMATION ===== //
5/*
6 IMPORTANT: rendering will be better for analyzing the model if fast-csg is enabled. As of writing, this feature is only available in the development builds and not the official release of OpenSCAD, but it makes rendering only take a couple seconds, even for comically large bins. Enable it in Edit > Preferences > Features > fast-csg
7
8https://github.com/kennetek/gridfinity-rebuilt-openscad
9
10*/
11
12// ===== PARAMETERS ===== //
13
14/* [Setup Parameters] */
15$fa = 8;
16$fs = 0.25;
17
18/* [General Settings] */
19// number of bases along x-axis
20gridx = 5;
21// number of bases along y-axis
22gridy = 5;
23
24/* [Screw Together Settings - Defaults work for M3 and 4-40] */
25// screw diameter
26d_screw = 3.35;
27// screw head diameter
28d_screw_head = 5;
29// screw spacing distance
30screw_spacing = .5;
31// number of screws per grid block
32n_screws = 1; // [1:3]
33
34
35/* [Fit to Drawer] */
36// minimum length of baseplate along x (leave zero to ignore, will automatically fill area if gridx is zero)
37distancex = 0;
38// minimum length of baseplate along y (leave zero to ignore, will automatically fill area if gridy is zero)
39distancey = 0;
40
41// where to align extra space along x
42fitx = 0; // [-1:0.1:1]
43// where to align extra space along y
44fity = 0; // [-1:0.1:1]
45
46
47/* [Styles] */
48
49// baseplate styles
50style_plate = 0; // [0: thin, 1:weighted, 2:skeletonized, 3: screw together, 4: screw together minimal]
51
52// enable magnet hole
53enable_magnet = true;
54
55// hole styles
56style_hole = 2; // [0:none, 1:countersink, 2:counterbore]
57
58
59// ===== IMPLEMENTATION ===== //
60screw_together = (style_plate == 3 || style_plate == 4);
61
62color("tomato")
63gridfinityBaseplate(gridx, gridy, l_grid, distancex, distancey, style_plate, enable_magnet, style_hole, fitx, fity);
64
65
66// ===== CONSTRUCTION ===== //
67
68module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, sm, sh, fitx, fity) {
69
70 assert(gridx > 0 || dix > 0, "Must have positive x grid amount!");
71 assert(gridy > 0 || diy > 0, "Must have positive y grid amount!");
72
73 gx = gridx == 0 ? floor(dix/length) : gridx;
74 gy = gridy == 0 ? floor(diy/length) : gridy;
75 dx = max(gx*length-bp_xy_clearance, dix);
76 dy = max(gy*length-bp_xy_clearance, diy);
77
78 off = calculate_off(sp, sm, sh);
79
80 offsetx = dix < dx ? 0 : (gx*length-bp_xy_clearance-dix)/2*fitx*-1;
81 offsety = diy < dy ? 0 : (gy*length-bp_xy_clearance-diy)/2*fity*-1;
82
83 difference() {
84 translate([offsetx,offsety,h_base])
85 mirror([0,0,1])
86 rounded_rectangle(dx, dy, h_base+off, r_base);
87
88 gridfinityBase(gx, gy, length, 1, 1, 0, 0.5, false);
89
90 translate([offsetx,offsety,h_base-0.6])
91 rounded_rectangle(dx*2, dy*2, h_base*2, r_base);
92
93 pattern_linear(gx, gy, length) {
94 render(convexity = 6) {
95
96 if (sp == 1)
97 translate([0,0,-off])
98 cutter_weight();
99 else if (sp == 2 || sp == 3)
100 linear_extrude(10*(h_base+off), center = true)
101 profile_skeleton();
102 else if (sp == 4)
103 translate([0,0,-5*(h_base+off)])
104 rounded_square(length-2*r_c2-2*r_c1, 10*(h_base+off), r_fo3);
105
106
107 hole_pattern(){
108 if (sm) block_base_hole(1);
109
110 translate([0,0,-off])
111 if (sh == 1) cutter_countersink();
112 else if (sh == 2) cutter_counterbore();
113 }
114 }
115 }
116 if (sp == 3 || sp ==4) cutter_screw_together(gx, gy, off);
117 }
118
119}
120
121function calculate_off(sp, sm, sh) =
122 screw_together
123 ? 6.75
124 :sp==0
125 ?0
126 : sp==1
127 ?bp_h_bot
128 :h_skel + (sm
129 ?h_hole
130 : 0)+(sh==0
131 ? d_screw
132 : sh==1
133 ?d_cs
134 :h_cb);
135
136module cutter_weight() {
137 union() {
138 linear_extrude(bp_cut_depth*2,center=true)
139 square(bp_cut_size, center=true);
140 pattern_circular(4)
141 translate([0,10,0])
142 linear_extrude(bp_rcut_depth*2,center=true)
143 union() {
144 square([bp_rcut_width, bp_rcut_length], center=true);
145 translate([0,bp_rcut_length/2,0])
146 circle(d=bp_rcut_width);
147 }
148 }
149}
150module hole_pattern(){
151 pattern_circular(4)
152 translate([l_grid/2-d_hole_from_side, l_grid/2-d_hole_from_side, 0]) {
153 render();
154 children();
155 }
156}
157
158module cutter_countersink(){
159 cylinder(r = r_hole1+d_clear, h = 100*h_base, center = true);
160 translate([0,0,d_cs])
161 mirror([0,0,1])
162 hull() {
163 cylinder(h = d_cs+10, r=r_hole1+d_clear);
164 translate([0,0,d_cs])
165 cylinder(h=d_cs+10, r=r_hole1+d_clear+d_cs);
166 }
167}
168
169module cutter_counterbore(){
170 cylinder(h=100*h_base, r=r_hole1+d_clear, center=true);
171 difference() {
172 cylinder(h = 2*(h_cb+0.2), r=r_cb, center=true);
173 copy_mirror([0,1,0])
174 translate([-1.5*r_cb,r_hole1+d_clear+0.1,h_cb-h_slit])
175 cube([r_cb*3,r_cb*3, 10]);
176 }
177}
178
179module profile_skeleton() {
180 l = l_grid-2*r_c2-2*r_c1;
181 minkowski() {
182 difference() {
183 square([l-2*r_skel+2*d_clear,l-2*r_skel+2*d_clear], center = true);
184 pattern_circular(4)
185 translate([l_grid/2-d_hole_from_side,l_grid/2-d_hole_from_side,0])
186 minkowski() {
187 square([l,l]);
188 circle(r_hole2+r_skel+2);
189 }
190 }
191 circle(r_skel);
192 }
193}
194
195module cutter_screw_together(gx, gy, off) {
196
197 screw(gx, gy);
198 rotate([0,0,90])
199 screw(gy, gx);
200
201 module screw(a, b) {
202 copy_mirror([1,0,0])
203 translate([a*l_grid/2, 0, -off/2])
204 pattern_linear(1, b, 1, l_grid)
205 pattern_linear(1, n_screws, 1, d_screw_head + screw_spacing)
206 rotate([0,90,0])
207 cylinder(h=l_grid/2, d=d_screw, center = true);
208 }
209}